package whf.framework.web.tag;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import whf.framework.log.Log;
import whf.framework.log.LogFactory;
import whf.framework.util.BeanUtils;
import whf.framework.util.Output;
import whf.framework.util.StringUtils;
import whf.framework.web.tag.ext.TagConstants;

/**
 * @author wanghaifeng
 *
 */
public class HtmlTag extends BodyTagSupport {
	private final static long serialVersionUID = 0;

	static Log log = LogFactory.getLog(HtmlTag.class);

	protected Map<String, String> attributeMap = new HashMap<String, String>();

	public void setClazz(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_CLASS, value);
	}

	public void setHtmlId(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_ID, value);
	}

	public void setName(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_NAME, value);
	}
	
	public void setValue(String value){
		this.setAttribute(TagConstants.ATTRIBUTE_VALUE, value);
	}

	public void setStyle(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_STYLE, value);
	}

	public void setTitle(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_TITLE, value);
	}

	public void setHeight(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_HEIGHT, value);
	}

	public void setWidth(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_WIDTH, value);
	}

	public void setBorder(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_BORDER, value);
	}

	public void setCellspacing(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_CELLSPACING, value);
	}

	public void setCellpadding(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_CELLPADDING, value);
	}

	public void setFrame(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_FRAME, value);
	}

	public void setRules(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_RULES, value);
	}

	public void setBgcolor(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_BGCOLOR, value);
	}

	public void setBackground(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_BACKGROUND, value);
	}

	public void setLang(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_LANG, value);
	}
	
	public void setDir(String value) {
		this.setAttribute(TagConstants.ATTRIBUTE_DIR, value);
	}
	
	public void setNowrap(String value){
		this.setAttribute(TagConstants.ATTRIBUTE_NOWRAP, value);
	}
	
	public void setSize(String value){
		this.setAttribute(TagConstants.ATTRIBUTE_SIZE, value);
	}
	
	public void setOnclick(String value){
		this.setAttribute(TagConstants.ATTRIBUTE_ONCLICK, value);
	}
	
	public void setOnchange(String value){
		this.setAttribute(TagConstants.ATTRIBUTE_ONCHANGE, value);
	}
	
	public void setAction(String value){
		this.setAttribute(TagConstants.ATTRIBUTE_ACTION, value);
	}
	
	public void setMultiple(String value){
		this.setAttribute(TagConstants.ATTRIBUTE_MULTIPLE, value);
	}
	
	/* (non-Javadoc)
	 * @see javax.servlet.jsp.tagext.TagSupport#getId()
	 */
	@Override
	public String getId() {
		return super.getId() == null?"": super.getId();
	}

	//
	public void setAttribute(String key, String value){
		this.attributeMap.put(key, value);
	}
	
	public String getAttribute(String key){
		return this.attributeMap.get(key);
	}
	
	public int getAttributeCount(){
		return this.attributeMap.keySet().size();
	}
	
	public String getHtmlAttribute(){
		StringBuffer sb = new StringBuffer(" ");
		for(Iterator it = this.attributeMap.keySet().iterator();it.hasNext();){
			String key = it.next().toString();
			sb.append(key).append("=").append("\"").append(attributeMap.get(key)).append("\" ");
		}
		return sb.toString();
	}
	
	public String getOpenTag(String tag){

		if (getAttributeCount() == 0) {
			return TagConstants.TAG_OPEN + tag + TagConstants.TAG_CLOSE;
		}

		StringBuffer buffer = new StringBuffer();

		buffer.append(TagConstants.TAG_OPEN).append(tag);

		buffer.append(getHtmlAttribute());

		buffer.append(TagConstants.TAG_CLOSE);

		return buffer.toString();
	}

	public String getCloseTag(String tag) {
		return TagConstants.TAG_OPENCLOSING + tag + TagConstants.TAG_CLOSE;
	}
	//

	public void release() {
		this.attributeMap.clear();
		this.output = null;
		super.release();
	}

	public Map getAttributeMap() {
		return this.attributeMap;
	}
	
	public HttpServletRequest request(){
		return (HttpServletRequest)this.pageContext.getRequest();
	}
	
	public HttpServletResponse response(){
		return (HttpServletResponse)this.pageContext.getResponse();
	}
	
	public HttpSession session(){
		return request().getSession();
	}
	
	public JspWriter out(){
		return this.pageContext.getOut();
	}
	
	public void flush(){
		try{
			this.pageContext.getOut().flush();
		}catch(Exception e){
			//ignore
		}
	}
	
	private Output output;
	
	public Output getOutput() {
		if(output == null)output = new Output(out());
		return this.output;
	}
	
	public Output println(Object text) throws JspException{
		if(output == null)output = new Output(out());
		try{
			output.println(text);
			return output;
		}catch(IOException e){
			throw new JspException(e);
		}
	}
	
	public Output print(Object text) throws JspException{
		if(output == null)output = new Output(out());
		try{
			output.print(text);
			return output;
		}catch(IOException e){
			throw new JspException(e);
		}
	}
	
	protected Output printInput(String type, String name, String value) throws JspException{
		return println("<input type='"+type+"' name='"+name+"' id='"+name+"' value='"+value+"' >");
	}
	
	protected Output printInput(String type, String name, String value, Map<String, String> otherProperties) throws JspException{
		StringBuilder sb = new StringBuilder();
		if(otherProperties != null){
			for(String propName: otherProperties.keySet()){
				String propValue = otherProperties.get(propName);
				if(propValue != null) //对于属性名－值的情况
					sb.append(" ").append(propName).append("='").append(propValue).append("' ");
				else //对于单值属性的情况
					sb.append(" ").append(propName).append(" ");
			}
		}
		return println("<input type='"+type+"' name='"+name+"' value='"+value+"' "+sb.toString()+" >");
	}
	
	protected Output printTd(String text) throws JspException{
		if(StringUtils.isEmpty(text)) text = "";
		return println("<td>"+text+"</td>");
	}
	
	protected Output printTd(String text, Map<String, String> otherProperties) throws JspException{
		StringBuilder sb = new StringBuilder();
		if(otherProperties != null){
			for(String propName: otherProperties.keySet()){
				String propValue = otherProperties.get(propName);
				sb.append(" ").append(propName).append("='").append(propValue).append("' ");
			}
		}
		return println("<td "+sb.toString()+">"+text+"</td>");
	}
	
	public static void main(String[] args) throws Exception{
		System.out.println(BeanUtils.hasProperty(TagConstants.class, "TAG_OPEN"));
	}
}
